package com.bicon.botu.mall.goods.service.impl;

import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.bicon.botu.mall.goods.commons.GoodsConstants;
import com.bicon.botu.mall.goods.entity.NoticeOfReduction;
import com.bicon.botu.mall.goods.entity.ProductRepertory;
import com.bicon.botu.mall.goods.service.NoticeOfReductionService;
import com.bicon.botu.mall.goods.vo.NoticeOfReductionVo;
import com.bicon.botu.mall.goods.vo.PriceDownNoticeVo;
import com.bicon.botu.core.base.common.Constants;
import com.bicon.botu.core.base.common.entity.BaseResult;
import com.bicon.botu.core.base.common.utils.DateUtil;
import com.bicon.botu.core.base.common.utils.StringUtils;
import com.bicon.botu.core.base.repository.redis.RedisHandler;
import com.bicon.botu.mall.goods.entity.Product;
import com.bicon.botu.mall.goods.mapper.NoticeOfReductionMapper;
import com.bicon.botu.third.provider.rpc.service.MessageRpcService;
import com.fasterxml.jackson.databind.ser.Serializers;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import java.math.BigDecimal;
import java.util.*;

/**
 * 降价通知ServiceImpl实现类
 *
 * @Author 刘齐
 * @Date 2017/7/25 10:14
 */
@Slf4j
@Service
@Transactional
public class NoticeOfReductionServiceImpl extends ServiceImpl<NoticeOfReductionMapper, NoticeOfReduction> implements
        NoticeOfReductionService {
    //降价通知Mapper
    @Autowired
    NoticeOfReductionMapper noticeOfReductionMapper;

    //导入redis缓存类
    @Autowired
    RedisHandler redisHandler;

    @Autowired
    MessageRpcService thirdPartRpc;


    @Value("${jpush.appkey}")
    private String appkey;

    @Value("${jpush.master}")
    private String master;

    @Value("${rpc.repeat.times}")
    int rpcRepeatTimes;

    /**
     * 降价通知redis key
     */
    private final String NOTICEREDIS = GoodsConstants.BOTU + GoodsConstants.REDIS_KEY_DELIMITER + GoodsConstants.MALL
            + GoodsConstants.REDIS_KEY_DELIMITER + GoodsConstants.GOODS + GoodsConstants.REDIS_KEY_DELIMITER
            + GoodsConstants.NOTICEOFREDUCTION + GoodsConstants.REDIS_KEY_DELIMITER;

    /**
     * 降价通知ServiceImpl
     *
     * @param userId             用户ID
     * @param productRepertoryId 产品库存ID
     * @param hopePrice          期望价格
     * @param notice             是否短信通知 0:通知 1:不通知
     * @return
     */
    @Override
    public BaseResult save(@RequestParam String userId,
                           @RequestParam String productRepertoryId,
                           @RequestParam BigDecimal hopePrice,
                           @RequestParam String notice) {
        if (hopePrice.doubleValue() < 0) {
            return new BaseResult(Constants.RESPONSE_CODE_401, Constants.RESPONSE_MESSAGE_401, "参数不能为负数");
        }
        //根据库存ID得到实体对象
        ProductRepertory productRepertory = new ProductRepertory().selectOne(
                new EntityWrapper<ProductRepertory>().eq("id", productRepertoryId).eq("logic_delete", Constants.DEL_LOGIC_NORMAL));
        if (productRepertory == null) {
            return new BaseResult(Constants.RESPONSE_CODE_602, Constants.RESPONSE_MESSAGE_602);
        }
        //根据库存商品ID查询商品对象
        Product product = new Product().selectOne(
                new EntityWrapper<ProductRepertory>().eq("id", productRepertory.getProductId()).eq("logic_delete", Constants.DEL_LOGIC_NORMAL));
        if (product == null) {
            return new BaseResult(Constants.RESPONSE_CODE_602, Constants.RESPONSE_MESSAGE_602);
        }
        //从redis中获取用户
        String userInfoStr = redisHandler.getGlobalRedisTemplate().getStringValue(Constants.BOTU_USER_USER_INFO, userId);
        if (userInfoStr == null) {
            return new BaseResult(Constants.RESPONSE_CODE_602, Constants.RESPONSE_MESSAGE_602);
        }
        //获取用户电话和用户名
        JSONObject json = JSONObject.parseObject(userInfoStr.toString());
        if (json == null) {
            return new BaseResult(Constants.RESPONSE_CODE_602, Constants.RESPONSE_MESSAGE_602);
        }
        String phone = json.get("phone").toString();
        if (StringUtils.isEmpty(phone)) {
            return new BaseResult(Constants.RESPONSE_CODE_500, Constants.RESPONSE_MESSAGE_500);
        }
        String name = json.get("name").toString();
        if (StringUtils.isEmpty(name)) {
            return new BaseResult(Constants.RESPONSE_CODE_500, Constants.RESPONSE_MESSAGE_500);
        }

        /**
         * 判断是否已有降价通知记录
         */
        NoticeOfReduction entity = new NoticeOfReduction().selectOne(new EntityWrapper<NoticeOfReduction>()
                .eq("product_repertoryId", productRepertoryId).eq("user_id", userId).eq("logic_delete", Constants.DEL_LOGIC_NORMAL));
        /**
         * 判断是否已有降价通知记录，如果有则修改期望价格和短信的状态
         */
        if (entity != null) {
            entity.setHopePrice(hopePrice);
            entity.setNotice(notice);
            entity.setState("0");
            entity.setState(GoodsConstants.PRODUCT_UNSEND_MESSAGE);
            entity.preUpdate();
            boolean result = entity.updateById();
            if (result) {
                redisHandler.getLocalRedisTemplate().removeHash(NOTICEREDIS, entity.getProductRepertoryId(), entity.getId());
                redisHandler.getLocalRedisTemplate().cacheHash(NOTICEREDIS, entity.getProductRepertoryId(), entity.getId(), JSONObject.toJSONString(entity));
                return new BaseResult(Constants.RESPONSE_CODE_200, Constants.RESPONSE_MESSAGE_200, "商品期望价格修改成功");
            }
            return new BaseResult(Constants.RESPONSE_CODE_600, Constants.RESPONSE_MESSAGE_600);
        }
        NoticeOfReduction noticeOfReduction = new NoticeOfReduction();
        noticeOfReduction.preInsert();
        noticeOfReduction.setUserId(userId);
        noticeOfReduction.setUserName(name);
        noticeOfReduction.setProductRepertoryId(productRepertoryId);
        noticeOfReduction.setProductId(product.getId());
        noticeOfReduction.setMobilePhoneNo(phone);
        noticeOfReduction.setHopePrice(hopePrice);
        //设置系统通知状态
        noticeOfReduction.setMerchantState(GoodsConstants.PRODUCT_UNSEND_MESSAGE);
        //设置商家通知状态
        noticeOfReduction.setState(GoodsConstants.PRODUCT_UNSEND_MESSAGE);
        //0:系统通知和商家通知 1：商家通知
        noticeOfReduction.setNotice(notice);
        boolean result = noticeOfReduction.insert();
        if (result) {
            //缓存到redis中
            redisHandler.getLocalRedisTemplate().cacheHash(NOTICEREDIS, noticeOfReduction.getProductRepertoryId(), noticeOfReduction.getId(), JSONObject.toJSONString(noticeOfReduction));
            return new BaseResult(Constants.RESPONSE_CODE_200, Constants.RESPONSE_MESSAGE_200, "商品的当前价格:" + productRepertory.getPrice());
        }
        return new BaseResult(Constants.RESPONSE_CODE_600, Constants.RESPONSE_MESSAGE_600);

    }


    /**
     * 点击按钮发送降价通知方法
     *
     * @param id 降价通知ID
     * @return
     */
    @Override
    public BaseResult merchantsNotice(@RequestParam String id) {
        //获取所有降价记录
        NoticeOfReduction reduction = new NoticeOfReduction().selectOne(new EntityWrapper().eq("id", id).eq("logic_delete", Constants.DEL_LOGIC_NORMAL));
        Map<String, String> map2 = new HashedMap();

        if (null != reduction && reduction.getState().equals(GoodsConstants.PRODUCT_UNSEND_MESSAGE)) {
            ProductRepertory productRepertory = new ProductRepertory().selectById(reduction.getProductRepertoryId());
            if (reduction.getNotice().equals(GoodsConstants.PRODUCT_NOTICE_MESSAGE)) {
                if (reduction.getHopePrice().doubleValue() < productRepertory.getPrice().doubleValue()) {
                    return new BaseResult(Constants.RESPONSE_CODE_200, "未达到期望价格");
                }
                //极光推送
                Product product = new Product().selectOne(new EntityWrapper().eq("id", reduction.getProductId())
                        .eq("logic_delete", Constants.DEL_LOGIC_NORMAL));
                String noticeContext = product.getProductName() + productRepertory.getSkuName();
                String[] user2 = new String[]{reduction.getUserId()};
                map2.put("productId", reduction.getProductId());
                //降价通知
                map2.put("type", "1");
                BaseResult jsonString = thirdPartRpc.pushAllTargetByUser(noticeContext + "已降价", "修改商品价格时主动调用通知1", map2, user2, appkey, master);
                log.debug("极光推送返回结果" + jsonString);
                //短信通知
                BaseResult resultJson = thirdPartRpc.sendYunSms(reduction.getMobilePhoneNo(), "(" + noticeContext + ")", "notice");
                log.info(JSONUtils.toJSONString(resultJson));
            } else {
                Product product = new Product().selectOne(new EntityWrapper().eq("id", reduction.getProductId())
                        .eq("logic_delete", Constants.DEL_LOGIC_NORMAL));
                String noticeContext = product.getProductName() + productRepertory.getSkuName();
                String[] user2 = new String[]{reduction.getUserId()};
                map2.put("productId", reduction.getProductId());
                //降价通知
                map2.put("type", "1");
                BaseResult jsonString = thirdPartRpc.pushAllTargetByUser(noticeContext + "已降价", "修改商品价格时主动调用通知1", map2, user2, appkey, master);
                log.info(JSONUtils.toJSONString(jsonString));
            }
            reduction.setState(GoodsConstants.PRODUCT_SEND_MESSAGE);
            reduction.updateById();
        }

        return new BaseResult(Constants.RESPONSE_CODE_200, Constants.RESPONSE_MESSAGE_200, "没有要通知的用户");
    }


    /**
     * 系统通知
     *
     * @param priceDownNoticeVoList 降价通知Vo类
     * @return
     */
    @Override
    public BaseResult systemInfo(@RequestParam List<PriceDownNoticeVo> priceDownNoticeVoList) {
        //获取所有降价通知记录
        NoticeOfReduction noticeOfReduction = null;
        Map<Object, Object> map = new HashedMap();
        Map<String, String> map2 = new HashedMap();
        String[] user2 = new String[200];
        int i = 0;
        //记录通知客户数量
        int record = 0;
        for (PriceDownNoticeVo priceDownNoticeVo : priceDownNoticeVoList) {
            map = redisHandler.getLocalRedisTemplate().getHashMap(NOTICEREDIS, priceDownNoticeVo.getRepertoryId());
            for (Object entity : map.values()) {
                String name = entity.toString();
                noticeOfReduction = JSONObject.parseObject(name, NoticeOfReduction.class);
                /**
                 * 根据仓库ID得到商品仓库对象
                 */
                ProductRepertory productRepertory = new ProductRepertory().selectById(priceDownNoticeVo.getRepertoryId());
                //获取商品三个月后的时间
                Calendar calendar = new GregorianCalendar();
                calendar.setTime(noticeOfReduction.getCreateDate());
                //把日期往后增加三个月.整数往后推,负数往前移动
                calendar.add(Calendar.DAY_OF_MONTH, 3);
                //判断商品是否超过三个月
                boolean result = DateUtil.calculateIntervalSecond(calendar.getTime(), new Date());
                if (result) {
                    //时间超出跳出
                    break;
                }
                if (noticeOfReduction.getHopePrice().doubleValue() >= priceDownNoticeVo.getProductPrice().doubleValue()) {
                    NoticeOfReduction ofReduction = new NoticeOfReduction().selectById(noticeOfReduction.getId());
                    if (null != ofReduction) {
                        if (ofReduction.getMerchantState().equals(GoodsConstants.PRODUCT_UNSEND_MESSAGE)) {
                            if (noticeOfReduction.getNotice().equals(GoodsConstants.PRODUCT_NOTICE_MESSAGE)) {
                                //极光推送
                                Product product = new Product().selectOne(new EntityWrapper().eq("id", productRepertory.getProductId())
                                        .eq("logic_delete", Constants.DEL_LOGIC_NORMAL));
                                String noticeContext = product.getProductName() + productRepertory.getSkuName();
                                user2[i] = noticeOfReduction.getUserId();
                                map2.put("productId", noticeOfReduction.getProductId());
                                //降价通知
                                map2.put("type", "1");
                                BaseResult jsonString = thirdPartRpc.pushAllTargetByUser(noticeContext + "已降价", "", map2, user2, appkey, master);
                                log.debug("极光推送返回结果" + jsonString);
                                //短信通知
                                BaseResult resultJson = thirdPartRpc.sendYunSms(noticeOfReduction.getMobilePhoneNo(), "(" + noticeContext + ")", "notice");
                            } else if (noticeOfReduction.getNotice().equals(GoodsConstants.PRODUCT_UNNOTICE_MESSAGE)) {
                                Product product = new Product().selectOne(new EntityWrapper().eq("id", productRepertory.getProductId())
                                        .eq("logic_delete", Constants.DEL_LOGIC_NORMAL));
                                String noticeContext = productRepertory.getSkuName() + product.getProductName();
                                user2[i] = noticeOfReduction.getUserId();
                                map2.put("productId", noticeOfReduction.getProductId());
                                //降价通知
                                map2.put("type", "1");
                                thirdPartRpc.pushAllTargetByUser(noticeContext + "已降价", "", map2, user2, appkey, master);
                            }
                            //被动通知已发送
                            noticeOfReduction.setMerchantState(GoodsConstants.PRODUCT_NOTICE_MESSAGE);
                            noticeOfReduction.updateById();
                        }
                    }
                }

                record++;
            }
            i++;
        }
        if (record == 0) {
            return new BaseResult(Constants.RESPONSE_CODE_200, Constants.RESPONSE_MESSAGE_200, "没有可通知用户");
        }
        return new BaseResult(Constants.RESPONSE_CODE_200, Constants.RESPONSE_MESSAGE_200, "用户通知完毕");

    }

    /**
     * 降价通知分页
     *
     * @param page 分页对象
     * @return
     */
    @Override
    public List<NoticeOfReductionVo> selectNoticePage(Page<NoticeOfReductionVo> page) {

        return noticeOfReductionMapper.selectNoticePage(page);
    }


    /**
     * 降价通知初始化
     */
//    @PostConstruct
    public void init() {
        System.out.println("启动。。。。。");
        //项目启动时缓存关系型数据库中数据到Redis
        EntityWrapper entityWrapper = new EntityWrapper();
        entityWrapper.eq("logic_delete", GoodsConstants.DEL_LOGIC_NORMAL)
                .eq("state", 0);
        List<NoticeOfReduction> newsControlList = noticeOfReductionMapper.selectList(entityWrapper);
        //初始化缓存时清除之前的数据
        redisHandler.getLocalRedisTemplate().removeOneOfList(NOTICEREDIS, "");
        for (NoticeOfReduction entity : newsControlList) {
            redisHandler.getLocalRedisTemplate().cacheHash(NOTICEREDIS, "", entity.getId(), JSONObject.toJSONString(entity));
        }

    }
}
